package cn.zc.curriculum.service.service.impl;

import cn.tools.core.VO.PageVO;
import cn.tools.core.exception.BizException;
import cn.tools.core.utils.mybatis.PageUtil;
import cn.tools.dozer.config.DozerUtils;

import cn.zc.curriculum.entity.DOS.QuestionBankDOS;
import cn.zc.curriculum.entity.Dto.QuestionBankDto;
import cn.zc.curriculum.entity.Dto.QuestionOptionDto;
import cn.zc.curriculum.entity.QuestionBank;
import cn.zc.curriculum.entity.QuestionOption;
import cn.zc.curriculum.entity.VO.QuestionBankVO;
import cn.zc.student.feign.FeignStudentExercisesRespondence;
import cn.zc.student.feign.FeignStudentExercisesResult;
import cn.zc.curriculum.service.mapper.QuestionBankMapper;
import cn.zc.curriculum.service.service.QuestionBankService;
import cn.zc.curriculum.service.service.QuestionOptionService;
import cn.zc.student.entity.Dto.StudentExercisesRespondenceDto;
import cn.zc.student.entity.StudentExercisesRespondence;
import cn.zc.tools.security.utils.SecurityUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 题库 服务实现类
 * </p>
 *
 * @author keno
 * @since 2022-02-14
 */
@Service
public class QuestionBankServiceImpl extends ServiceImpl<QuestionBankMapper, QuestionBank> implements QuestionBankService {

    @Resource
    private DozerUtils dozerUtils;

    @Resource
    private QuestionOptionService questionOptionService;

    @Resource
    private QuestionBankMapper questionBankMapper;

    @Resource
    private FeignStudentExercisesRespondence feignStudentExercisesRespondence;

    @Resource
    private FeignStudentExercisesResult feignStudentExercisesResult;

    @Resource
    private SecurityUtils securityUtils;

    /**
     * 创建练习题
     * @param questionBankDto
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void createQuestionBank(QuestionBankDto questionBankDto) {
        QuestionBank bank = dozerUtils.map(questionBankDto, QuestionBank.class);
        if(!save(bank)){
            throw new BizException("创建题失败");
        }

        for (QuestionOptionDto questionOptionDto:questionBankDto.getQuestionOption()) {
            QuestionOption option = dozerUtils.map(questionOptionDto, QuestionOption.class);
            option.setQuestionId(bank.getId());
            if(!questionOptionService.createQuestionOption(option)){
                throw new BizException("创建题选项失败");
            };
        }
    }


    /**
     * 修改练习题
     * @param questionBankDto
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void updateQuestionBank(QuestionBankDto questionBankDto) {
        QuestionBank bank = dozerUtils.map(questionBankDto, QuestionBank.class);
        if(!updateById(bank)){
            throw new BizException("修改题失败");
        }
        for (QuestionOptionDto questionOptionDto:questionBankDto.getQuestionOption()) {
            QuestionOption option = dozerUtils.map(questionOptionDto, QuestionOption.class);
            option.setQuestionId(bank.getId());
            if(!questionOptionService.updateQuestionOption(option)){
                throw new BizException("修改题选项失败");
            };
        }
    }


    /**
     * 删除练习题
     * @param id
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void deleteQuestionBank(String id) {
        if(!removeById(id)){
            throw new BizException("删除练习题失败");
        }

        questionOptionService.deleteQuestionOptionByBank(id);
    }


    /**
     * 查询练习题
     * @param pageVO
     * @param questionBankVO
     * @return
     */
    @Override
    public List<QuestionBankDto> findQuestionBank(PageVO pageVO, QuestionBankVO questionBankVO) {
        List<QuestionBankDto> bankDto = questionBankMapper.findQuestionBank(PageUtil.initPage(pageVO),questionBankVO);

        return bankDto;
    }

    /**
     * 根据目录id查询练习题
     * @param pageVO
     * @param menuId
     * @return
     */
    @Override
    public List<QuestionBankDto> findQuestionBankByMenu(PageVO pageVO ,String menuId) {
        List<QuestionBankDto> bankDto = questionBankMapper.findQuestionBankByMenu(PageUtil.initPage(pageVO),menuId);
        return bankDto;
    }

    /**
     * 学生提交作答
     * @param menuId
     * @param questionBankDOS
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public Integer pushStudentQuestionBank(String menuId, List<QuestionBankDOS> questionBankDOS) {
        Integer studentScore = null;
        String studentId = securityUtils.getSecurityUser().getId();
        ArrayList<StudentExercisesRespondence> list = new ArrayList<>();

        for (QuestionBankDOS questionBank:questionBankDOS) {
            if(questionBank.getRightAnswers().equals(questionBank.getSelector())){
                studentScore = studentScore + Integer.parseInt(questionBank.getRightAnswers());
            }

            StudentExercisesRespondence studentExercisesRespondence = new StudentExercisesRespondence();
            studentExercisesRespondence.setMenuId(menuId);
            studentExercisesRespondence.setStudentId(studentId);
            studentExercisesRespondence.setQuestionId(questionBank.getQuestionId());
            studentExercisesRespondence.setSelector(questionBank.getSelector());

            list.add(studentExercisesRespondence);
        }

        if(!feignStudentExercisesRespondence.createStudentExercisesRespondence(list)){
            throw new BizException("保存作答记录失败");
        }

        if(!feignStudentExercisesResult.createStudentExercisesResult(menuId,studentId,String.valueOf(studentScore))){
            throw new BizException("保存练习题成绩失败");
        }

        return studentScore;
    }


    /**
     * 根据目录id与学生id查询出学生本次练习题作业成绩
     * @param pageVO
     * @param menuId
     * @return
     */
    @Override
    public List<QuestionBankDto> findStudentQuestionBank(PageVO pageVO,String menuId) {
        String studentId = securityUtils.getSecurityUser().getId();
        List<StudentExercisesRespondenceDto> studentExercisesRespondence = feignStudentExercisesRespondence.findStudentExercisesRespondence(menuId, studentId);
        List<QuestionBankDto> questionBankByMenu = findQuestionBankByMenu(pageVO, menuId);
        if(questionBankByMenu == null){
            throw new BizException("练习题题不存在");
        }
        for (QuestionBankDto questionBank : questionBankByMenu) {
            for (StudentExercisesRespondenceDto studentExercisesRespondenceDto:studentExercisesRespondence) {
                if(questionBank.getId().equals(studentExercisesRespondenceDto.getQuestionId())){
                    questionBank.setStudentExercisesRespondence(studentExercisesRespondenceDto);
                }
            }
        }

        return questionBankByMenu;
    }
}
